// global var
var db;
//var mykey;
var map;
var service;
var infowindow;
var pageUnit = 20;
var server_url = "http://savemykids-gae.appspot.com";
//var server_url = "http://localhost:8080";


$(document).bind("mobileinit", function(){
    $.mobile.page.prototype.options.addBackBtn = true;
    document.addEventListener("deviceready", onDeviceReady, false);
});




function onDeviceReady() {
    navigator.network.isReachable(server_url, reachableCallback, {});
    
    document.addEventListener(
        "backbutton",
        function(e) {
            if ($('.ui-page-active').attr('id') == 'launcher_page') {
                navigator.app.exitApp();
            } else {
                goBack();
            }
        },
        false
    );
}

$(document).ready(
    function() {
        $('img.launcher-button-image').retina('@2x');
        //$('img').retina();
        
        //document.addEventListener("deviceready", onDeviceReady, false);
    
        // frequently used author name or pen name
        if (localStorage.freqName == undefined) {
            localStorage.freqName = '';
        }
        
        // page
        sessionStorage.allPageOffset = 0;
        sessionStorage.myPageOffset = 0;
        
        // db
        var shortName = 'savemykids';
        var version = '1.0';
        var displayName = shortName;
        var maxSize = 65536;
        db = openDatabase(shortName, version, displayName, maxSize);
        db.transaction(
            function(transaction) {
                transaction.executeSql(
                    'CREATE TABLE IF NOT EXISTS mykey (' +
                    'id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' +
                    'mainKey TEXT NOT NULL, ' +
                    'replyKey TEXT);'
                );
            }
        );
    
        //detectBrowser();
        //$('#hospitals_page_button').click(clickHospitalsPageButton);
        $('#hospitals_page').live('pageshow', clickHospitalsPageButton);
        
        //$('#talks_page_button').click(clickTalksPageButton);
        $('#talks_page').live('pageshow', clickTalksPageButton);
        
        
        $('#reply_form').submit(submitReplyForm);
        $('#newposting_form').submit(submitNewPostingForm);
        
        //$('#view_allposting_button').click(clickViewAllPostingButton);
        $('#view_allposting_button').live('tap', clickViewAllPostingButton);
        
        //$('#view_myposting_button').click(clickViewMyPostingButton);
        $('#view_myposting_button').live('tap', clickViewMyPostingButton);
        
        
        //$('#view_nextpage_button').click(clickViewNextPageButton);
        $('#view_nextpage_button').live('tap', clickViewNextPageButton);
        
        $('#newposting_button').click(clickNewPostingButton);
        
        /*
        // ignore scroll!
        document.body.addEventListener(
            'touchmove',
            function(event) {
                if ($(document).height() <= $(window).height()) {
                    event.preventDefault();
                }
            },
            false
        );
        */
        
        /*
        // fast click - no click delay
        $('.noclickdelay').each(
            function(i, node) {
                new NoClickDelay(node);
            }
        );
        */
    }
);


/******************************************************************************
 *
 * Utility functions
 *
 *****************************************************************************/
 /*
function NoClickDelay(el) {
    this.element = el;
    if( window.Touch ) this.element.addEventListener('touchstart', this, false);
}

NoClickDelay.prototype = {
    handleEvent: function(e) {
        switch(e.type) {
            case 'touchstart': this.onTouchStart(e); break;
            case 'touchmove': this.onTouchMove(e); break;
            case 'touchend': this.onTouchEnd(e); break;
        }
    },

    onTouchStart: function(e) {
        e.preventDefault();
        this.moved = false;
        this.element.addEventListener('touchmove', this, false);
        this.element.addEventListener('touchend', this, false);
    },

    onTouchMove: function(e) {
        this.moved = true;
    },

    onTouchEnd: function(e) {
        this.element.removeEventListener('touchmove', this, false);
        this.element.removeEventListener('touchend', this, false);

    if( !this.moved ) {
        var theTarget = document.elementFromPoint(e.changedTouches[0].clientX, e.changedTouches[0].clientY);
        if(theTarget.nodeType == 3) theTarget = theTarget.parentNode;
            var theEvent = document.createEvent('MouseEvents');
            theEvent.initEvent('click', true, true);
            theTarget.dispatchEvent(theEvent);
        }
    }
};
*/


function reachableCallback(reachability) {
    // There is no consistency on the format of reachability
    var networkState = reachability.code || reachability;
    
    var states = {};
    states[NetworkStatus.NOT_REACHABLE] = 'No network connection';
    states[NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK] = 'Carrier data connection';
    states[NetworkStatus.REACHABLE_VIA_WIFI_NETWORK] = 'WiFi connection';
    
    if (networkState == NetworkStatus.NOT_REACHABLE) {
        alert('Connection type: ' + states[networkState]);
    }
}


function checkConnection() {
    var networkState = navigator.network.connection.type;
    
    var states = {};
    states[Connection.UNKNOWN]  = 'Unknown connection';
    states[Connection.ETHERNET] = 'Ethernet connection';
    states[Connection.WIFI]     = 'WiFi connection';
    states[Connection.CELL_2G]  = 'Cell 2G connection';
    states[Connection.CELL_3G]  = 'Cell 3G connection';
    states[Connection.CELL_4G]  = 'Cell 4G connection';
    states[Connection.NONE]     = 'No network connection';
    
    alert('Connection type: ' + states[networkState]);
}

function detectBrowser() {
    var useragent = navigator.userAgent;
    var mapdiv = document.getElementById("map");
    
    if (useragent.indexOf('iPhone') != -1 || useragent.indexOf('Android') != -1) {
        mapdiv.style.width = '100%';
        mapdiv.style.height = '50%';
    } else {
        mapdiv.style.width = '600px';
        mapdiv.style.height = '800px';
    }
}

function goBack() {
    history.back();
    return false;
}

function saveKey(mainKey, replyKey) {
    db.transaction(
        function(transaction) {
            transaction.executeSql(
                'INSERT INTO mykey (mainKey, replyKey) VALUES (?, ?);', 
                [mainKey, replyKey],
                function() {},
                errorHandler
            );
        }
    );
}
function deleteKey(mainKey, replyKey) {
    db.transaction(
        function(transaction) {
            transaction.executeSql(
                'DELETE FROM mykey WHERE mainKey=? AND replyKey=?;', 
                [mainKey, replyKey],
                function() {},
                errorHandler
            );
        }
    );
}
function fetchKey() {
    db.transaction(
        function(transaction) {
            transaction.executeSql(
                'SELECT DISTINCT mainKey FROM mykey;', 
                [], 
                function (transaction, result) {
                    var keyArray = new Array();
                    for (var i=0; i < result.rows.length; i++) {
                        var row = result.rows.item(i);
                        keyArray.push(row.mainKey);
                    }
                    // fetch complete!
                    fetchPostings(keyArray.join());
                }, 
                errorHandler
            );
        }
    );
}
function errorHandler(transaction, error) {
    alert('Oops. Error was '+error.message+' (Code '+error.code+')');
    return true;
}

function utcToKST(utctime) {
    var utc_time = utctime.split('.')[0];
    var kst_time = Date.parse(utc_time).setTimezoneOffset(+0000);
    return kst_time;
}

function initGeolocation(success_callback, error_callback, options) {
    if (typeof(navigator.geolocation) != 'undefined') {
        navigator.geolocation.getCurrentPosition(success_callback, error_callback, options);
    } else {
    }
}

function onGeolocationSuccess(position) {
}

function onGeolocationError(error) {
    switch(error.code) {  
        case error.PERMISSION_DENIED:
            alert(error.message);
            //alert("user did not share geolocation data");  
            break;  
        
        case error.POSITION_UNAVAILABLE:
            alert(error.message);
            //alert("could not detect current position");  
            break;  
        
        case error.TIMEOUT:
            alert(error.message);
            //alert("retrieving position timed out");  
            break;  
        
        default:
            //alert(error.message);
            alert("unknown error");  
            break;  
    }
}

/*****************************************************************************/
function isAllPostingMode() {
    var allPosting = false;
    //var classes = $('#view_allposting_button').attr('class');
    
    var classes = $('#view_allposting_button').attr('class').split(' ');
    jQuery.each(classes, function() {
        if (this == 'ui-btn-active') {
            allPosting = true;
        }
    });
    
    return allPosting;
}

function clickViewNextPageButton() {
    $('#view_nextpage_button').removeClass('ui-btn-active');
    if (isAllPostingMode() == true) {
        sessionStorage.allPageOffset += pageUnit;
    } else {
        sessionStorage.myPageOffset += pageUnit;
    }
    clickTalksPageButton();
    return false;
}


function clickViewMyPostingButton() {
    $('#view_allposting_button').removeClass('ui-btn-active');
    $('#view_myposting_button').addClass('ui-btn-active');
    
    sessionStorage.allPageOffset = 0;
    
    // view only my posting
    clickTalksPageButton();
}

function clickViewAllPostingButton() {
    $('#view_allposting_button').addClass('ui-btn-active');
    $('#view_myposting_button').removeClass('ui-btn-active');
    
    sessionStorage.myPageOffset = 0;
    
    // view all posting
    clickTalksPageButton();
}

function clickNewPostingButton() {
    if (localStorage.freqName != '') {
        $('#newposting_author').val(localStorage.freqName);
    }
}

function submitNewPostingForm(event) {
    var author = $('#newposting_author').val();
    var title = $('#newposting_title').val();
    var content = $('#newposting_textarea').val();
    
    if (author == '' || author == undefined ||
        title == '' || title == undefined ||
        content == '' || content == undefined) {
        alert('이름, 제목, 글 내용을 모두 입력해주세요.');
        return;
    }
    
    localStorage.freqName = author;
    
    var newposting = {
        posting: {
            author: author,
            title: title,
            content: content,
            type: "main",
            category: "qna"
        }
    };
    
    var req = $.toJSON(newposting);
    
    $.ajax({
        url: server_url + "/api/posting",
        type: "POST",
        data: req,
        dataType: "json",
        contentType: "application/json",
        complete: postNewQnACallback
    });
    
    $('#newposting_author').val('');
    $('#newposting_title').val('');
    $('#newposting_textarea').text('');
    
    return false;
}

function postNewQnACallback(data) {
    // check success or fail
    var statusCode = data.status;
    if (statusCode != '200') {
        // Fail !!
        alert('글 입력에 실패했습니다.');
        goBack();
        return;
    }    
    
    var key = data.responseText;
    
    // save key
    saveKey(key, '');
    
    sessionStorage.allPostingPageOffset = 0;
    sessionStorage.myPostingPageOffset = 0;
    clickTalksPageButton();
    
    goBack();
}

// When the talks menu in launcher page is pressed...
function fetchPostings(keylist) {
    if (keylist == undefined) {
        $.mobile.pageLoading();
        $.ajax({
            url: server_url + "/api/posting",
            type: 'GET',
            data: {
                offset: sessionStorage.allPageOffset,
                feq_category: 'qna',
                feq_type: 'main',
                ordering: '-date'
            },
            dataType: 'json',
            complete: getQnACallback
        });
        
    } else if (keylist == '') {
        //alert('No mykey');
    } else {
        $.mobile.pageLoading();
        $.ajax({
            url: server_url + "/api/posting",
            type: 'GET',
            data: {
                offset: sessionStorage.myPageOffset,
                feq_category: 'qna',
                feq_type: 'main',
                fin_key: keylist,
                ordering: '-date'
            },
            dataType: 'json',
            complete: getQnACallback
        });
        
    }
}
function clickTalksPageButton() {    
    
    // all posting...
    if (isAllPostingMode() == true) {
        if (sessionStorage.allPageOffset == 0) {
            $('#talks_page_content ul li:gt(0)').remove();
        }
        fetchPostings();
        
    } else { // my posting...
        if (sessionStorage.myPageOffset == 0) {
            $('#talks_page_content ul li:gt(0)').remove();
        }
        fetchKey();
    }
    
}


// When specific QnA list item is clicked...
function clickReadQnA() {
    
    $.mobile.pageLoading();

    var index = $("#talks_ul li").index(this);
    sessionStorage.currentQnAIndex = index;
    
    var p = $(this).data('posting');

    // if this posting's nr_reply is greater than 0, it needs to fetch replies
    $('#reply_ul li:gt(1)').remove();
    if (p.nr_reply > 0) {
        $.ajax({
            url: server_url + "/api/posting",
            type: 'GET',
            data: {
                feq_category: 'qna',
                feq_type: 'reply',
                feq_mainThread: p.key,
                ordering: '-date'
            },
            dataType: 'json',
            complete: displayReplyListCallback
        });
    }
    
    var kst = utcToKST(p.date);
    var kst_time = kst.toString('yyyy/MM/dd h:mm:ss tt dddd');
                    
    // Display readposting page elements
    $('.readingposting_title').text(p.title);
    $('.readingposting_author_date').text('By ' + p.author + ' (' + kst_time + ')');
    $('.readingposting_content').text(p.content);
    
    //$('#readposting_page_header h1').text(p.title);
    
    if (localStorage.freqName != '') {
        $('#reply_form_author').val(localStorage.freqName);
    }
    
    
    sessionStorage.mainKey = p.key;
    sessionStorage.title = p.title;
    sessionStorage.nr_reply = p.nr_reply;
        
}

function displayQnAList(qna) {
    
    var kst = utcToKST(qna.date);
    var kst_time = kst.toString('yyyy/MM/dd h:mm:ss tt dddd');
    
    var row = $('#talks_li_template').clone();
    row.removeAttr('id');
    row.removeAttr('style');
    row.data('posting', qna);
    row.appendTo('#talks_ul');
            
    row.find('.posting-title-span').text(qna.title);
    row.find('.posting-content-span').text(qna.content);
    row.find('.posting-nr-reply-span').text(qna.nr_reply);
    row.find('.posting-author-date-span').text(qna.author + ' (' + kst_time + ')');
    
            
    //row.click(clickReadQnA);
    row.bind('tap', clickReadQnA);
}

// GET postings callback
function getQnACallback(data) {

    // check success or fail
    var statusCode = data.status;
    if (statusCode != '200') {
        // Fail !!
        $.mobile.pageLoading(true);
        alert('글을 읽어오는데 실패했습니다.');
        return;
    }    
    
    // parse json
    var response = jQuery.parseJSON(data.responseText);

    var nr_posting;
    var postings = response.list.posting;
    if (postings != undefined) {
        nr_postings = postings.length;
        if (nr_postings == undefined) {
            nr_postings = 1;
        }
    } else {
        $.mobile.pageLoading(true);
        //alert("No posting...");
        if (isAllPostingMode() == true) {
            if (sessionStorage.allPageOffset > 0) {
                sessionStorage.allPageOffset -= pageUnit;
            }
        } else {
            if (sessionStorage.myPageOffset > 0) {
                sessionStorage.myPageOffset -= pageUnit;
            }
        }
        return;
    }
    
    if (nr_postings == 1) { /* only 1 posting */
        displayQnAList(postings);
    } else { /* 2+ postings */
        for (var i = 0; i < nr_postings; ++i) {
            displayQnAList(postings[i]);
        } // end of for loop
    } // end of if - else
    
    $.mobile.pageLoading(true);
    
} // end of talks_page_get_callback function


function displayReplyList(reply) {
    var row = $('#reply_li_template').clone();
    row.removeAttr('id');
    row.removeAttr('style');
    row.appendTo('#reply_ul');
    row.find('.reply-content-span').text(reply.content);
    
    var kst = utcToKST(reply.date);
    var kst_time = kst.toString('yyyy/MM/dd h:mm:ss tt dddd');
    
    row.find('.reply-author-date-span').text('By ' + reply.author + ' (' + kst_time + ')');
}

/* Show reply messages when showing posting's content page */
function displayReplyListCallback(data) {
    $('#reply_ul li:gt(1)').remove();
    
    // check success or fail
    var statusCode = data.status;
    if (statusCode != '200') {
        // Fail !!
        $.mobile.pageLoading(true);
        alert('댓글을 읽어오는데 실패했습니다.');
        return;
    }
    
    // parse json
    var response = jQuery.parseJSON(data.responseText);

    var nr_posting;
    var postings = response.list.posting;
    if (postings != undefined) {
        nr_postings = postings.length;
        if (nr_postings == undefined) {
            nr_postings = 1;
        }
    } else {
        $.mobile.pageLoading(true);
        //alert("No reply...");
        return;
    }
    
    if (nr_postings == 1) { // 1 reply
        displayReplyList(postings);
    } else { // 2+ reply
        for (var i = 0; i < nr_postings; ++i) {
            displayReplyList(postings[i]);
        } // end of for        
    } // end of if-else
    
    $.mobile.pageLoading(true);
}


function postReplyCallback(data) {
    // check success or fail
    var statusCode = data.status;
    if (statusCode != '200') {
        // Fail !!
        $.mobile.pageLoading(true);
        alert('댓글 입력에 실패했습니다.');
        return;
    }
    
    var replyKey = data.responseText;
    
    // save key (not replyKey!! note! save sessionStorage.mainKey !!)
    saveKey(sessionStorage.mainKey, replyKey);
    
    /*
    var findKey = false;
    jQuery.each(mykey, function() {
        if (this == sessionStorage.mainKey) {
            findKey = true;
        }
    });
    if (findKey == false) {
        mykey.push(sessionStorage.mainKey);
        localStorage.mykey = mykey.join();
    }*/
    
    
    
    // modify main message's nr_reply (++nr_reply)
    var posting = {
        posting: {
            nr_reply: parseInt(sessionStorage.nr_reply) + 1
        }
    };
    var req = $.toJSON(posting);
    $.ajax({
        url: server_url + "/api/posting/" + sessionStorage.mainKey,
        type: 'POST',
        data: req,
        dataType: 'json',
        contentType: 'application/json',
        complete: postReplyNumberCallback
    });
    
    // add new reply element to reply list
    //displayReplyList(sessionStorage.replyAuthor, sessionStorage.replyContent);
}

// Modify main message's nr_reply field
// Currently, this function is not used.
function postReplyNumberCallback(data) {
    $('#reply_ul li:gt(1)').remove();
    
    // After submiting the reply message, reload current QnA page
    $('#talks_ul li').eq(sessionStorage.currentQnAIndex).trigger('tap');
    
    // After submiting the reply message, reload current QnA list page.
    // Although this reloading action is not visible, it is need
    // Cuz when a user pressed back button, QnA list page should show correct reply number.
    clickTalksPageButton();

    $.mobile.pageLoading(true);
}

// Writing reply message handler
function submitReplyForm(event) {
    
    var author = $('#reply_form_author').val();
    var title = 're: ' + sessionStorage.title;
    var content = $('#reply_form_content').val();
    var mainKey = sessionStorage.mainKey;
    
    
    if (author == undefined || author == '' ||
        content == undefined || content == '' ||
        mainKey == undefined || mainKey == '') {
        // fill forms!
        alert("이름과 내용을 입력해주세요.");
        return false;
    }
    
    localStorage.freqName = author;
    
    $.mobile.pageLoading();
    
    sessionStorage.replyContent = content;
    sessionStorage.replyAuthor = author;
    
    
    // register reply message - REST POST
    var reply = {
        posting: {
            author: author,
            title: title,
            content: content,
            type: 'reply',
            category: 'qna',
            mainThread: mainKey
        }
    };
    
    var req = $.toJSON(reply);
    $.ajax({
        url: server_url + "/api/posting",
        type: 'POST',
        complete: postReplyCallback,
        data: req,
        dataType: 'json',
        contentType: 'application/json'
    });
    
    $('#reply_form_author').val('');
    $('#reply_form_content').text('');
    
    return false;
}

function clickHospitalsPageButton() {
    $('#hospitals_ul li:gt(1)').remove();
    initGeolocation(handlePosition, onGeolocationError, {timeout:15000, maximumAge:60000});
    $.mobile.pageLoading();
    /*
    if (typeof(navigator.geolocation) != 'undefined') {
        navigator.geolocation.getCurrentPosition(handlePosition);
    } else {
    }
    */
}



function handlePosition(pos) {
    //alert("Your location is: " + pos.coords.latitude + ', ' + pos.coords.longitude);
    var loc = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
    var req = {
        location: loc,
        name: '소아과',
        radius: '1000',
        types: ['hospital', 'health', 'establishment']
    };
    
    map = new google.maps.Map(
        document.getElementById('map'),
        {
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            center: loc,
            zoom: 15
        }
    );
    var meMarker = new google.maps.Marker(
        {
            map: map, 
            position: loc
        }
    );
    
    service = new google.maps.places.PlacesService(map);
    //service = new google.maps.places.PlacesService('hospital_details_div');
    
    //$.mobile.pageLoading();
    service.search(req, mapLocationHandler);
    
    infowindow = new google.maps.InfoWindow();
}

function mapLocationHandler(results, status) {
    $.mobile.pageLoading(true);
    if (status == google.maps.places.PlacesServiceStatus.OK) {
        for (var i = 0; i < results.length; ++i) {
            var place = results[i];
            var request = {reference: place.reference};
            
            $.mobile.pageLoading();
            service.getDetails(request, getHospitalDetails);
            
            //createMarker(results[i]);
            //createHospitalItem(results[i].reference);
        }
        $('#hospitals_ul').listview('refresh');
    } else if (status == google.maps.places.PlacesServiceStatus.INVALID_REQUEST) {
        alert("invalid request");
    } else if (status == google.maps.places.PlacesServiceStatus.OVER_QUERY_LIMIT) {
        alert("over query limit");
    } else if (status == google.maps.places.PlacesServiceStatus.REQUEST_DENIED) {
        alert("reqeust denied");
    } else if (status == google.maps.places.PlacesServiceStatus.UNKOWN_ERROR) {
        alert("unknown error");
    } else if (status == google.maps.places.PlacesServiceStatus.ZERO_RESULTS) {
        alert("zero results");
    }
}

function getHospitalDetails(place, status) {
    $.mobile.pageLoading(true);
    if (status == google.maps.places.PlacesServiceStatus.OK) {
        var item = '<li><a href=' + place.url + '><h3>' + place.name + '</h3><p>' + place.formatted_phone_number + '</p></a></li>';
        $('#hospitals_ul').append(item);
        /*
        var row = $('#hospitals_ul_template').clone();
        row.removeAttr('id');
        row.removeAttr('style');
        row.data('url', place.url);
        row.data('name', place.name);
        row.appendTo('#hospitals_ul');
        row.find('.hospitalNameSpan').text(place.name);
        row.find('.hospitalPhoneSpan').text(place.formatted_phone_number);
        row.click(
            function() {
                var name = $(this).data('name');
                var url = $(this).data('url');
                $('#hospital_details_page_title').text(name);
                $('#hospital_details_div').load(url);
                //$.mobile.changePage('#hospital_details_page');
            }
        );
        */
        
        $('#hospitals_ul').listview('refresh');
    }
}

function createMarker(place) {
    var row = $('#hospitals_ul_template').clone();
    row.removeAttr('id');
    row.removeAttr('style');
    //row.data('place_reference', place.reference);
    row.appendTo('#hospitals_ul');
    row.find('.hospitalName').text(place.name);
    row.find('.hospitalAddr').text(place.vicinity);
    row.click(
        function() {
            var req = {reference: place.reference};
            var ds = service.getDetails(req, getHospitalInfo);
        }
    );
    
    var placeLoc = place.geometry.location;
    var marker = new google.maps.Marker(
        {
            map: map,
            position: new google.maps.LatLng(placeLoc.lat(), placeLoc.lng()),
            icon: 'images/hospital_map_icon.png'
        }
    );
    google.maps.event.addListener(
        marker, 
        'click', 
        function() {
            infowindow.setContent(place.name);
            infowindow.open(map, this);
        }
    );
}

function getHospitalInfo(place, status) {
    if (status == google.maps.places.PlacesServiceStatus.OK) {
        var url = place.url;
        $.get(url, function(data) {
                window.location = url;
            }
        );
    }
}
